home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / BDTOQRY.PAK / OWLQRY.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  13KB  |  490 lines

  1. // (C) Copyright 1996, Borland International
  2. //
  3. // Owlqry.cpp - VDBT Tquery example
  4. /*******************************************************************************
  5. This example demonstrates how hook up to a database table and then
  6. navigate through it using the VDBT Tquery object.  The user can navigate
  7. through the table using the Main Menu items or via the keyboard. Only one
  8. record will be displayed at a time.
  9.  
  10.  
  11.     SETTING UP TO USE AN EVENT HANDLER
  12.  
  13.     Visual Database Tools uses event sources and event sinks (or
  14.     handlers) to encapsulate everything necessary for repsonding
  15.     to event.  The general     steps are:
  16.     1.  Identify the source that will be the source of the events
  17.          you wish to handle, in this particular example, TDataSource.  This is
  18.          done in the MainCreateMsg function.
  19.     2.  Define the event sink to handle the event.  This is done as part of
  20.          the EventHandler class.
  21.     3.  Connect the event sink to the event handler.  This is done as part of
  22.          The EventHandle constructor.
  23.     4.  Connect the event source to the event sink.  This is done in the
  24.          MainCreateMsg function.
  25.  
  26.  
  27. The BIOLIFE table in the diveplan database is used by default.  A different
  28. database and table can be specified on as command line arguments.
  29.  
  30. The files needed to build this program are:
  31.  
  32. owlqry.cpp            Source file for application
  33. owlqry.rc            Resource file for application
  34. owlqry.ico            Icon file for application
  35. owlqry16/32.def    def file for 16bit target and 32bit target respectively
  36. makefile                makefile for command-line tools build
  37. owlqry.ide            BCW 5.0 project file to build both 32bit and 16bit
  38.                         versions of owlqry.
  39. *******************************************************************************/
  40.  
  41.  
  42. #include <vdbt\bdto.h>
  43. #include <windowsx.h>
  44. #include "resource.h"
  45.  
  46. /******************************************************************************/
  47.  
  48. #define NOTUSED( x )        ((void)(long) (x))
  49.  
  50. #define DATABASENAME "DivePlan"
  51. #define SQLTEXT "Select * from \"biolife.db\""
  52.  
  53. #define MAIN_CLASS_NAME    "Main Class"
  54.  
  55. /******************************************************************************/
  56. // function prototypes
  57.  
  58. BOOL RegisterMainClass( HINSTANCE hInstance );
  59.  
  60. HWND CreateMainWindow( HINSTANCE hInstance, LPSTR lpszCmdLine, int cmdShow );
  61.  
  62. extern "C" LRESULT CALLBACK _export MainWndProc( HWND hwnd, UINT msg,
  63.                                                                 WPARAM wParam, LPARAM lParam );
  64.                                                 
  65. void MainCreateMsg( HWND hwnd, LPSTR lpszCmdLine );
  66.  
  67. void MainPaintMsg( HWND hwnd );
  68.  
  69. void GetAndDrawGraphic( HDC hdc, TGraphicField& graphic, int x, int y, 
  70.                                                                                     int w, int h );
  71.                                                                
  72. void GetAndDisplayMemo( HDC hdc, TMemoField& memo,int top, int width,
  73.                                                                                         int height);
  74.  
  75. void DrawPrettyText(HDC hdc, string PrintString, int left, int top, int width,
  76.                                                                                         int height);
  77.                                                                   
  78. BOOL MainCommandMsg( HWND hwnd, WPARAM wParam, LPARAM lParam );
  79.  
  80. void MainKeyDownMsg( HWND hwnd, WPARAM wParam );
  81.  
  82. void MainDestroyMsg( HWND hwnd );
  83.  
  84. #define EXTRA sizeof(TQuery*) + sizeof(TDataSource*) + sizeof(EventHandler*)
  85. #define SWL_QUERY 0
  86. #define SWL_DATASOURCE 4
  87. #define SWL_EVENTHANDLER 8
  88.  
  89. /******************************************************************************/
  90.  
  91. class EventHandler
  92. {
  93. private:
  94.     HWND hwnd;
  95. public:
  96.     EventHandler( HWND h );
  97.     TDataChangeSink OnDataChangeSink;
  98. protected:
  99.     void OnDataChange( TDataChangeSink& sink, TDataSource& sender, TField* field );
  100. };
  101.  
  102. EventHandler::EventHandler( HWND h ):
  103.   OnDataChangeSink( TDataChange_MFUNCTOR( *this, &EventHandler::OnDataChange ) )
  104. {
  105.     hwnd = h;
  106. }
  107.  
  108. void EventHandler::OnDataChange( TDataChangeSink&, TDataSource&, TField* )
  109. {
  110.     if (hwnd)
  111.     {
  112.         RECT rc;
  113.         GetClientRect( hwnd, &rc );
  114.         rc.left = rc.right/2;
  115.         InvalidateRect( hwnd, &rc, TRUE );
  116.     }
  117. }
  118.  
  119. /******************************************************************************/
  120.  
  121. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow )
  122. {
  123.     if (! hPrevInstance)
  124.         if (! RegisterMainClass(hInstance))
  125.             return 0;
  126.  
  127.     CreateMainWindow(hInstance, lpszCmdLine, cmdShow);
  128.  
  129.     MSG msg;
  130.     while (GetMessage(&msg, (HWND) 0, 0, 0))
  131.     {
  132.         TranslateMessage(&msg);
  133.         DispatchMessage(&msg);
  134.     }
  135.  
  136.     return 0;
  137. }
  138.  
  139. /******************************************************************************/
  140.  
  141. BOOL RegisterMainClass( HINSTANCE hInstance )
  142. {
  143.     WNDCLASS wndClass;
  144.  
  145.     wndClass.style = CS_HREDRAW | CS_VREDRAW;
  146.     wndClass.lpfnWndProc = MainWndProc;
  147.     wndClass.cbClsExtra = 0;
  148.     wndClass.cbWndExtra = EXTRA;
  149.     wndClass.hInstance = hInstance;
  150.     wndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN));
  151.     wndClass.hCursor = LoadCursor((HINSTANCE) 0, IDC_ARROW);
  152.     wndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
  153.     wndClass.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN);
  154.     wndClass.lpszClassName = MAIN_CLASS_NAME;
  155.  
  156.     return RegisterClass(&wndClass);
  157. }
  158.  
  159. /******************************************************************************/
  160.  
  161. HWND CreateMainWindow( HINSTANCE hInstance, LPSTR lpszCmdLine, int cmdShow )
  162. {
  163.     char    szTitle[30 + 1];
  164.     HWND    hwnd;
  165.  
  166.     LoadString(hInstance, IDS_MAINTITLE, szTitle, 30);
  167.     hwnd = CreateWindow(MAIN_CLASS_NAME, szTitle, WS_TILEDWINDOW,
  168.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  169.         (HWND) 0, (HMENU) 0, hInstance, lpszCmdLine);
  170.  
  171.     if (hwnd)
  172.     {
  173.         ShowWindow(hwnd, cmdShow);
  174.         UpdateWindow(hwnd);
  175.     }
  176.  
  177.     return hwnd;
  178. }
  179.  
  180. /******************************************************************************/
  181.  
  182. extern "C" LRESULT CALLBACK _export MainWndProc(HWND hwnd, UINT msg,
  183.                                                                     WPARAM wParam, LPARAM lParam)
  184. {
  185.     switch (msg)
  186.     {
  187.         case WM_CREATE:
  188.             MainCreateMsg(hwnd, (LPSTR) ((LPCREATESTRUCT) lParam)->lpCreateParams);
  189.             break;
  190.  
  191.         case WM_PAINT:
  192.             MainPaintMsg(hwnd);
  193.             break;
  194.  
  195.         case WM_COMMAND:
  196.             if (! MainCommandMsg(hwnd, wParam, lParam))
  197.                 return DefWindowProc(hwnd, msg, wParam, lParam);
  198.             break;
  199.  
  200.         case WM_KEYDOWN:
  201.             MainKeyDownMsg(hwnd, wParam);
  202.             break;
  203.  
  204.         case WM_DESTROY:
  205.             MainDestroyMsg(hwnd);
  206.             PostQuitMessage(0);
  207.             break;
  208.  
  209.         default:
  210.             return DefWindowProc(hwnd, msg, wParam, lParam);
  211.     }
  212.  
  213.     return 0L;
  214. }
  215.  
  216. /******************************************************************************/
  217.  
  218. void MainCreateMsg(HWND hwnd, LPSTR lpszCmdLine)
  219. {
  220.     // Parse the command line for the alias and sql query.
  221.  
  222.     LPSTR databaseName = DATABASENAME;
  223.     LPSTR sqlText = SQLTEXT;
  224.     if (*lpszCmdLine)
  225.     {
  226.         LPSTR space = strchr( lpszCmdLine, ' ');
  227.         if (space)
  228.         {
  229.             *space = '\0';
  230.             sqlText = space+1;
  231.             databaseName = lpszCmdLine;
  232.         }
  233.     }
  234.  
  235.     // Update the window's title bar with the database name and sql query.
  236.  
  237.     char    szTitle[30 + 200 + 1];
  238.     int len = GetWindowText( hwnd, szTitle, sizeof(szTitle) );
  239.     wsprintf( szTitle+len, " - :%s:%s", databaseName, sqlText );
  240.     SetWindowText( hwnd, szTitle );
  241.  
  242.     // Create the TQuery object.
  243.  
  244.     TQuery* query = new TQuery;
  245.     if (query)
  246.     {
  247.         // Put the database name and SQLText properties, execute the query.
  248.  
  249.         try
  250.         {
  251.             query->DatabaseName = string( databaseName );
  252.             query->SQL->Text = string(sqlText);
  253.             query->Open();
  254.         }
  255.         catch (BDTException e)
  256.         {
  257.             e.Show( "processing WM_CREATE" );
  258.             delete query;
  259.             query = NULL;
  260.         }
  261.         SetWindowLong( hwnd, SWL_QUERY, (LONG) query );
  262.  
  263.         if (query)
  264.         {
  265.             // Create a datasource object and attach to the OnDataChange event.
  266.  
  267.             EventHandler* handler = new EventHandler( hwnd );
  268.             if (handler)
  269.             {
  270.                 TDataSource* datasource = new TDataSource;
  271.                 if (datasource)
  272.                 {
  273.                     datasource->DataSet = query;
  274.                     datasource->OnDataChangeSource += handler->OnDataChangeSink;
  275.                     SetWindowLong( hwnd, SWL_DATASOURCE, (LONG) datasource );
  276.                 }
  277.                 SetWindowLong( hwnd, SWL_EVENTHANDLER, (LONG) handler );
  278.             }
  279.         }
  280.     }
  281. }
  282.  
  283. /******************************************************************************/
  284.  
  285. void MainPaintMsg(HWND hwnd)
  286. {
  287.     PAINTSTRUCT ps;
  288.     RECT rc;
  289.  
  290.     BeginPaint( hwnd, &ps );
  291.     GetClientRect( hwnd, &rc );
  292.  
  293.     TQuery* query = (TQuery*) GetWindowLong( hwnd, SWL_QUERY );
  294.     if (query)
  295.     {
  296.         int count = query->FieldCount;
  297.         if (count)
  298.         {
  299.             int width = rc.right/2;
  300.             int height = rc.bottom/count;
  301.  
  302.             // Paint the field names on the left side of the window, the
  303.             // field values on the right side of the window.
  304.  
  305.             int i;
  306.             for (i = 0; i < count; i++)
  307.             {
  308.                 string s = query->Fields[i]->FieldName;
  309.             //DrawPrettyText sets up the rectangle to contain the text so that
  310.             //DrawText can be used instead of TextOut.
  311.             DrawPrettyText(ps.hdc, s, 0, i*height, width, height);
  312.  
  313.                 if (query->Fields[i]->DataType == ftGraphic)
  314.                 {
  315.                     GetAndDrawGraphic( ps.hdc, TGraphicField(query->Fields[i]),
  316.                                         width, i*height, width, height );
  317.                 }
  318.                 else if (query->Fields[i]->DataType == ftMemo)
  319.                 {
  320.                     GetAndDisplayMemo( ps.hdc, TMemoField(query->Fields[i]), i*height, width,
  321.                                                                                        height );
  322.                 }
  323.                 else
  324.                 {
  325.                     s = query->Fields[i]->Text;
  326.                DrawPrettyText(ps.hdc, s, width, i*height, width, height);
  327.                 }
  328.             }
  329.         }
  330.     }
  331.  
  332.     EndPaint(hwnd, &ps);
  333. }
  334.  
  335. /******************************************************************************/
  336.  
  337. void GetAndDrawGraphic( HDC hdc, TGraphicField& graphic, int x, int y, int w,
  338.                                 int h )
  339. {
  340.     // Use the SaveToBitmap method to get the bitmap and palette handles.
  341.  
  342.     HBITMAP hbm = 0;
  343.     HPALETTE hpal = 0;
  344.     graphic.SaveToBitmap( hbm, hpal );
  345.     if (hbm)
  346.     {
  347.         HDC hdcTemp = CreateCompatibleDC( hdc );
  348.         if (hdcTemp)
  349.         {
  350.             BITMAP bm;
  351.             GetObject( hbm, sizeof(BITMAP), &bm );
  352.             HBITMAP hbmPrev = SelectBitmap( hdcTemp, hbm );
  353.             StretchBlt( hdc, x, y, w, h,
  354.                             hdcTemp, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY );
  355.             SelectBitmap( hdcTemp, hbmPrev );
  356.             DeleteDC( hdcTemp );
  357.         }
  358.         DeleteBitmap( hbm );
  359.     }
  360.     if (hpal)
  361.         DeletePalette( hpal );
  362. }
  363.  
  364. /******************************************************************************/
  365.  
  366. void GetAndDisplayMemo( HDC hdc, TMemoField& memo, int top, int width,
  367.                                 int height)
  368. {
  369.     TMemoryStream stream;
  370.     memo.SaveToStream( stream );
  371.     stream.Position = 0;
  372.     TStrings strings;
  373.     strings.LoadFromStream( stream );
  374.     string s = strings.Text;
  375.    DrawPrettyText(hdc, s, width, top, width, height);
  376. }
  377.  
  378. /******************************************************************************/
  379.  
  380. void DrawPrettyText(HDC hdc, string PrintString, int left, int top, int width,
  381.                             int height)
  382. {
  383.     RECT rc;
  384.     rc.left = left;
  385.     rc.top = top;
  386.     rc.right = rc.left + width;
  387.     rc.bottom = rc.top + height;
  388.     DrawText(hdc, PrintString.c_str(), PrintString.length(), &rc, DT_TOP | DT_LEFT | DT_WORDBREAK | DT_NOPREFIX );
  389. }
  390.  
  391. /******************************************************************************/
  392.  
  393. BOOL MainCommandMsg(HWND hwnd, WPARAM wParam, LPARAM lParam)
  394. {
  395.     NOTUSED( lParam );
  396.     // Process navigation commands from the menu.
  397.  
  398.     TQuery* query = (TQuery*) GetWindowLong( hwnd, SWL_QUERY );
  399.     if (query)
  400.     {
  401.         switch (GET_WM_COMMAND_ID(wParam, lParam))
  402.         {
  403.             case IDM_NAV_FIRST:
  404.                 query->First();
  405.                 break;
  406.             case IDM_NAV_PRIORSET:
  407.                 query->MoveBy(-5);
  408.                 break;
  409.             case IDM_NAV_PRIOR:
  410.                 query->Prior();
  411.                 break;
  412.             case IDM_NAV_NEXT:
  413.                 query->Next();
  414.                 break;
  415.             case IDM_NAV_NEXTSET:
  416.                 query->MoveBy(5);
  417.                 break;
  418.             case IDM_NAV_LAST:
  419.                 query->Last();
  420.                 break;
  421.             default:
  422.                 return FALSE;
  423.         }
  424.  
  425.         return TRUE;
  426.     }
  427.  
  428.     return FALSE;
  429. }
  430.  
  431. /******************************************************************************/
  432.  
  433. void MainKeyDownMsg(HWND hwnd, WPARAM wParam)
  434. {
  435.     // Process navigation commands from the keyboard.
  436.  
  437.     TQuery* query = (TQuery*) GetWindowLong( hwnd, SWL_QUERY );
  438.     if (query)
  439.     {
  440.         switch (wParam)
  441.         {
  442.             case VK_HOME:
  443.                 query->First();
  444.                 break;
  445.             case VK_PRIOR:
  446.                 query->MoveBy(-5);
  447.                 break;
  448.             case VK_UP:
  449.                 query->Prior();
  450.                 break;
  451.             case VK_DOWN:
  452.                 query->Next();
  453.                 break;
  454.             case VK_NEXT:
  455.                 query->MoveBy(5);
  456.                 break;
  457.             case VK_END:
  458.                 query->Last();
  459.                 break;
  460.         }
  461.     }
  462. }
  463.  
  464. /******************************************************************************/
  465.  
  466. void MainDestroyMsg( HWND hwnd )
  467. {
  468.     // Delete the query and the datasource.
  469.  
  470.     TQuery* query = (TQuery*) GetWindowLong( hwnd, SWL_QUERY );
  471.     SetWindowLong( hwnd, SWL_QUERY, 0 );
  472.     if (query)
  473.     {
  474.         TDataSource* datasource = (TDataSource*) GetWindowLong( hwnd, SWL_DATASOURCE );
  475.         SetWindowLong( hwnd, SWL_DATASOURCE, 0 );
  476.         if (datasource)
  477.             delete datasource;
  478.  
  479.         EventHandler* handler=(EventHandler*)GetWindowLong(hwnd, SWL_EVENTHANDLER);
  480.         SetWindowLong( hwnd, SWL_EVENTHANDLER, 0 );
  481.         if (handler)
  482.             delete handler;
  483.  
  484.         delete query;
  485.     }
  486. }
  487. /******************************************************************************/
  488.  
  489.  
  490.